/**
 * Copyright(c) 2014 Xunton Solutions
 *
 * History:
 *   15-12-8 上午11:30 Created by dwzhang
 */
package com.jade.modules.message.store.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.sql.SqlUtils;
import com.jade.framework.base.util.DataUtils;
import com.jade.framework.base.util.PagingList;
import com.jade.modules.message.store.MessageDao;
import com.jade.modules.message.store.MessageRecord;
import com.jade.modules.message.store.StoreException;
import org.apache.commons.lang3.StringUtils;

/**
 * 采用JPA方式实现的数据访问接口。
 *
 * @author <a href="mailto:dwzhang@xunton.com">dwzhang</a> 
 * @version 1.0 15-12-8 上午11:30
 */
@Named ("module_messageDao")
public class JpaMessageDao
        implements MessageDao
{
    private static final String SQL = "SELECT message FROM MessageRecord message";
    @PersistenceContext (unitName = "default")
    private EntityManager em;

    public void add(MessageRecord message)
            throws StoreException
    {
        em.persist(message);
    }

    public void update(MessageRecord message)
            throws StoreException
    {
        em.merge(message);
    }

    public void remove(MessageRecord message)
    {
        em.merge(message);
    }

    public int remove(String receiverType, String receiver, String category)
    {
        String sql = "DELETE FROM MessageRecord record WHERE receiverType=:receiverType AND" +
                " receiver=:receiver AND category=:category";
        Query query = em.createQuery(sql);
        query.setParameter("category", category);
        query.setParameter("receiverType", receiverType);
        query.setParameter("receiver", receiver);
        return query.executeUpdate();
    }

    public MessageRecord get(long id)
    {
        return em.find(MessageRecord.class, id);
    }

    public PagingList<MessageRecord> query(Criteria criteria)
    {
        return SqlUtils.sqlQuery(SQL, em, criteria);
    }

    public List<MessageRecord> list(Criteria criteria)
    {
        return SqlUtils.sqlQueryWithoutCount(SQL, em, criteria);
    }

    public long getNewMsgCount(String category, String receiverType, String receiver, Date time)
    {
        String sql = "SELECT count(id) FROM MessageRecord message where creationDate>=:time" +
                " and receiverType=:receiverType and receiver=:receiver and status=:status";

        if (StringUtils.isNotBlank(category)) {
            sql += " and message.category=:category";
        }
        Query query = em.createQuery(sql);
        if (StringUtils.isNotBlank(category)) {
            query.setParameter("category", category);
        }
        query.setParameter("receiverType", receiverType);
        query.setParameter("receiver", receiver);
        query.setParameter("time", time);
        query.setParameter("status", MessageRecord.STATUS_NEW);
        Number count = (Number) query.getSingleResult();
        return count.longValue();
    }

    public Map<String, Long> getNewMsgCountByCategory(String receiverType, String receiver, Date time)
    {
        String sql = "SELECT category, count(category) FROM MessageRecord message where creationDate>=:time" +
                " and receiverType=:receiverType and receiver=:receiver and status=:status GROUP by category";
        Query query = em.createQuery(sql);
        query.setParameter("receiverType", receiverType);
        query.setParameter("receiver", receiver);
        query.setParameter("time", time);
        query.setParameter("status", MessageRecord.STATUS_NEW);
        Map<String, Long> countMap = new HashMap<String, Long>();
        List<Object[]> objs = query.getResultList();
        for (Object[] array : objs) {
            countMap.put(array[0].toString(), DataUtils.getLong(array[1], 0));
        }
        return countMap;
    }
}
